package com.estore.network;

import com.estore.model.Product;
import com.estore.model.User;
import com.estore.model.UserRole;
import com.estore.sorter.ProductSorters;

import java.io.*;
import java.net.*;
import java.util.List;
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Comparator;
import java.util.Collections;


/**
 * 商城客户端
 */
public class EStoreClient {
    private static final String SERVER_HOST = "localhost";
    private static final int SERVER_PORT = 8888;

    private User currentUser = null;
    private final Map<String, Integer> shoppingCart = new HashMap<>();
    private final Scanner scanner = new Scanner(System.in);

    public void start() {
        System.out.println("=== 天天商城客户端系统启动 ===");

        // 首先显示登录/注册菜单
        while (currentUser == null) {
            showAuthMenu();
            int choice = getIntInput("请选择: ");

            switch (choice) {
                case 1:
                    login();
                    break;
                case 2:
                    register();
                    break;
                case 3:
                    System.out.println("感谢使用天天商城，再见！");
                    return;
                default:
                    System.out.println("无效的选项，请重新输入！");
            }
        }

        // 根据用户角色显示不同的主菜单
        if (currentUser.getRole() == UserRole.ADMIN) {
            showAdminMainMenu();
        } else {
            showCustomerMainMenu();
        }
    }

    private void showAuthMenu() {
        System.out.println("\n========== 用户认证 ==========");
        System.out.println("1. 登录");
        System.out.println("2. 注册");
        System.out.println("3. 退出");
    }

    private void showCustomerMainMenu() {
        while (true) {
            System.out.println("\n========== 天天商城 (客户模式) ==========");
            System.out.println("欢迎, " + currentUser.getUsername() + "!");
            System.out.println("1. 浏览所有商品");
            System.out.println("2. 自定义排序浏览商品");
            System.out.println("3. 管理购物车");
            System.out.println("4. 查看购物车详情");
            System.out.println("5. 结算购物车");
            System.out.println("6. 注销");
            System.out.print("请输入您的选择: ");

            int choice = getIntInput("");

            switch (choice) {
                case 1:
                    browseProducts();
                    break;
                case 2:
                    browseProductsWithSorting();
                    break;
                case 3:
                    manageCart();
                    break;
                case 4:
                    viewCartDetails();
                    break;
                case 5:
                    checkoutCart();
                    break;
                case 6:
                    currentUser = null;
                    System.out.println("注销成功！");
                    start(); // 返回认证菜单
                    return;
                default:
                    System.out.println("无效的选项，请重新输入！");
            }
        }
    }

    private void showAdminMainMenu() {
        while (true) {
            System.out.println("\n========== 天天商城 (管理员模式) ==========");
            System.out.println("欢迎, 管理员 " + currentUser.getUsername() + "!");
            System.out.println("1. 浏览所有商品");
            System.out.println("2. 自定义排序浏览商品");
            System.out.println("3. 添加新商品");
            System.out.println("4. 更新商品信息");
            System.out.println("5. 删除商品");
            System.out.println("6. 数据备份");
            System.out.println("7. 注销");
            System.out.print("请输入您的选择: ");

            int choice = getIntInput("");

            switch (choice) {
                case 1:
                    browseProducts();
                    break;
                case 2:
                    browseProductsWithSorting();
                    break;
                case 3:
                    addProduct();
                    break;
                case 4:
                    updateProductInfo();
                    break;
                case 5:
                    deleteProduct();
                    break;
                case 6:
                    backupData();
                    break;
                case 7:
                    currentUser = null;
                    System.out.println("注销成功！");
                    start(); // 返回认证菜单
                    return;
                default:
                    System.out.println("无效的选项，请重新输入！");
            }
        }
    }

    private void login() {
        System.out.print("用户名: ");
        String username = scanner.nextLine();
        System.out.print("密码: ");
        String password = scanner.nextLine();

        Object response = sendRequest("LOGIN", username, password);

        if (response instanceof User) {
            currentUser = (User) response;
            System.out.println("登录成功！欢迎, " + currentUser.getUsername() + "!");
        } else {
            System.out.println("登录失败：用户名或密码错误！");
        }
    }

    private void register() {
        System.out.print("请输入用户名: ");
        String username = scanner.nextLine();
        System.out.print("请输入密码: ");
        String password = scanner.nextLine();

        Object response = sendRequest("REGISTER", username, password);

        if (response instanceof Boolean && (Boolean) response) {
            System.out.println("注册成功！请使用新账户登录。");
        } else {
            System.out.println("注册失败：用户名已存在！");
        }
    }

    private void browseProducts() {
        System.out.println("\n--- 从服务器获取商品列表（默认排序） ---");

        Object response = sendRequest("GET_ALL_PRODUCTS");

        if (response instanceof List) {
            @SuppressWarnings("unchecked")
            List<Product> products = (List<Product>) response;

            // 默认按商品ID排序（自然排序）
            Collections.sort(products);

            System.out.println("--- 商品列表（按商品ID排序） ---");
            if (products.isEmpty()) {
                System.out.println("商店里还没有商品！");
            } else {
                System.out.println("共找到 " + products.size() + " 个商品：");
                products.forEach(System.out::println);
            }
        } else {
            System.out.println("服务器返回了意外的响应: " + response);
        }
    }

    private void browseProductsWithSorting() {
        System.out.println("\n--- 自定义排序浏览商品 ---");

        Object response = sendRequest("GET_ALL_PRODUCTS");

        if (!(response instanceof List)) {
            System.out.println("服务器返回了意外的响应: " + response);
            return;
        }

        @SuppressWarnings("unchecked")
        List<Product> products = (List<Product>) response;

        if (products.isEmpty()) {
            System.out.println("商店里还没有商品！");
            return;
        }

        // 显示排序选项
        System.out.println("请选择排序方式:");
        System.out.println("1. 按商品ID排序（默认）");
        System.out.println("2. 按价格从低到高");
        System.out.println("3. 按价格从高到低");
        System.out.println("4. 按库存从多到少");
        System.out.print("请输入您的选择: ");

        int sortChoice = getIntInput("");
        String sortDescription = "";
        Comparator<Product> comparator = null;

        switch (sortChoice) {
            case 1:
                // 使用自然排序（按ID）
                comparator = null; // 使用自然排序
                sortDescription = "按商品ID排序";
                break;
            case 2:
                comparator = ProductSorters.BY_PRICE_ASC;
                sortDescription = "按价格从低到高";
                break;
            case 3:
                comparator = ProductSorters.BY_PRICE_DESC;
                sortDescription = "按价格从高到低";
                break;
            case 4:
                comparator = ProductSorters.BY_STOCK_DESC;
                sortDescription = "按库存从多到少";
                break;
            default:
                System.out.println("无效的选择，使用默认排序！");
                sortDescription = "按商品ID排序";
        }

        // 执行排序
        if (comparator != null) {
            products.sort(comparator);
        } else {
            Collections.sort(products); // 自然排序
        }

        System.out.println("\n--- 商品列表 (" + sortDescription + ") ---");
        System.out.println("共找到 " + products.size() + " 个商品：");
        products.forEach(System.out::println);
    }

    private void manageCart() {
        while (true) {
            System.out.println("\n--- 管理购物车 ---");
            // 先显示当前购物车状态
            viewCartDetails();

            System.out.println("\n请选择操作:");
            System.out.println("1. 添加商品到购物车");
            System.out.println("2. 从购物车移除商品");
            System.out.println("3. 修改购物车商品数量");
            System.out.println("4. 清空购物车");
            System.out.println("5. 返回主菜单");
            System.out.print("请选择操作: ");

            int choice = getIntInput("");

            switch (choice) {
                case 1:
                    addToCart();
                    break;
                case 2:
                    removeFromCart();
                    // 移除后显示购物车详情
                    viewCartDetails();
                    break;
                case 3:
                    updateCartQuantity();
                    // 修改数量后显示购物车详情
                    viewCartDetails();
                    break;
                case 4:
                    clearCart();
                    // 清空后显示购物车详情
                    viewCartDetails();
                    break;
                case 5:
                    return;
                default:
                    System.out.println("无效的选择，请重新输入！");
            }
        }
    }

    private void addToCart() {
        while (true) {
            System.out.println("\n--- 添加商品到购物车 ---");
            System.out.print("请输入要添加的商品ID (输入 'quit' 退出): ");
            String productId = scanner.nextLine().trim();

            if ("quit".equalsIgnoreCase(productId)) {
                break;
            }

            // 先检查商品是否存在
            List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
            Product product = products.stream()
                    .filter(p -> p.getId().equals(productId))
                    .findFirst()
                    .orElse(null);

            if (product == null) {
                System.out.println("商品不存在，请检查商品ID！");
                continue;
            }

            System.out.println("商品信息: " + product);
            System.out.print("请输入购买数量: ");
            int quantity = getIntInput("");

            if (quantity <= 0) {
                System.out.println("购买数量必须为正数！");
                continue;
            }

            // 检查库存：考虑购物车中已有的数量
            int currentCartQuantity = shoppingCart.getOrDefault(productId, 0);
            int totalRequestedQuantity = currentCartQuantity + quantity;

            if (totalRequestedQuantity > product.getStock()) {
                int availableQuantity = product.getStock() - currentCartQuantity;
                System.out.println("库存不足！");
                System.out.println("购物车中已有数量: " + currentCartQuantity);
                System.out.println("当前库存: " + product.getStock());
                System.out.println("最多还能添加: " + (availableQuantity > 0 ? availableQuantity : 0) + " 件");
                continue;
            }

            // 将商品加入购物车
            shoppingCart.put(productId, totalRequestedQuantity);

            // 计算总金额
            double totalAmount = product.getPrice() * totalRequestedQuantity;
            System.out.println("添加成功！");
            System.out.printf("商品ID: %s | 名称: %s | 数量: %d | 单价: ¥%.2f | 总金额: ¥%.2f\n",
                    productId, product.getName(), totalRequestedQuantity,
                    product.getPrice(), totalAmount);

            // 添加后显示购物车详情
            viewCartDetails();

            System.out.print("是否继续添加商品? (y/n): ");
            String continueInput = scanner.nextLine().trim();
            if (!continueInput.equalsIgnoreCase("y")) {
                break;
            }
        }
    }

    private void removeFromCart() {
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车是空的！");
            return;
        }

        System.out.print("请输入要移除的商品ID: ");
        String productId = scanner.nextLine().trim();

        if (!shoppingCart.containsKey(productId)) {
            System.out.println("购物车中没有该商品！");
            return;
        }

        int removedQuantity = shoppingCart.remove(productId);
        System.out.println("已从购物车移除商品: " + productId + "，数量: " + removedQuantity);
    }

    private void updateCartQuantity() {
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车是空的！");
            return;
        }

        System.out.print("请输入要修改数量的商品ID: ");
        String productId = scanner.nextLine().trim();

        if (!shoppingCart.containsKey(productId)) {
            System.out.println("购物车中没有该商品！");
            return;
        }

        int currentQuantity = shoppingCart.get(productId);
        System.out.println("当前数量: " + currentQuantity);
        System.out.print("请输入新的数量: ");
        int newQuantity = getIntInput("");

        if (newQuantity <= 0) {
            shoppingCart.remove(productId);
            System.out.println("数量设置为0，已从购物车移除该商品");
            return;
        }

        // 检查库存
        List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
        Product product = products.stream()
                .filter(p -> p.getId().equals(productId))
                .findFirst()
                .orElse(null);

        if (product == null) {
            System.out.println("商品不存在！");
            return;
        }

        if (newQuantity > product.getStock()) {
            System.out.println("库存不足！当前库存: " + product.getStock());
            System.out.println("最大可设置数量: " + product.getStock());
            return;
        }

        shoppingCart.put(productId, newQuantity);
        System.out.println("已更新商品数量: " + productId + " -> " + newQuantity);
    }

    private void clearCart() {
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车已经是空的！");
            return;
        }

        System.out.print("确定要清空购物车吗? (y/n): ");
        String confirm = scanner.nextLine().trim();
        if (confirm.equalsIgnoreCase("y")) {
            shoppingCart.clear();
            System.out.println("购物车已清空！");
        }
    }

    private void viewCartDetails() {
        System.out.println("\n--- 购物车详情 ---");
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车是空的，快去逛逛吧！");
            return;
        }

        // 获取所有商品信息
        List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
        Map<String, Product> productMap = new HashMap<>();
        for (Product product : products) {
            productMap.put(product.getId(), product);
        }

        System.out.println("==================================================================");
        System.out.println("商品ID | 商品名称               | 单价       | 数量 | 小计");
        System.out.println("==================================================================");

        double totalAmount = 0.0;
        int totalItems = 0;

        for (Map.Entry<String, Integer> entry : shoppingCart.entrySet()) {
            String productId = entry.getKey();
            Integer quantity = entry.getValue();
            Product product = productMap.get(productId);

            if (product != null) {
                double subtotal = product.getPrice() * quantity;
                System.out.printf("%-6s | %-20s | ¥%-8.2f | %-4d | ¥%.2f\n",
                        productId, product.getName(), product.getPrice(), quantity, subtotal);
                totalAmount += subtotal;
                totalItems += quantity;
            } else {
                System.out.printf("%-6s | %-20s | %-10s | %-4d | %s\n",
                        productId, "商品不存在", "N/A", quantity, "N/A");
            }
        }

        System.out.println("==================================================================");
        System.out.printf("总计: %d 件商品，合计金额: ¥%.2f\n", totalItems, totalAmount);
    }

    private void checkoutCart() {
        if (shoppingCart.isEmpty()) {
            System.out.println("购物车是空的，无法结算！");
            return;
        }

        // 先显示购物车详情
        viewCartDetails();

        System.out.print("\n确定要结算吗? (y/n): ");
        String confirm = scanner.nextLine().trim();
        if (!confirm.equalsIgnoreCase("y")) {
            System.out.println("取消结算");
            return;
        }

        System.out.println("\n--- 结算购物车 ---");
        double total = 0.0;
        boolean allSuccessful = true;
        Map<String, Integer> failedItems = new HashMap<>();

        // 逐个购买购物车中的商品
        for (Map.Entry<String, Integer> entry : shoppingCart.entrySet()) {
            String productId = entry.getKey();
            int quantity = entry.getValue();

            Object response = sendRequest("PURCHASE_PRODUCT", productId, quantity);

            if (response instanceof String && ((String) response).startsWith("SUCCESS")) {
                // 获取商品信息计算价格
                List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
                Product product = products.stream()
                        .filter(p -> p.getId().equals(productId))
                        .findFirst()
                        .orElse(null);

                if (product != null) {
                    double subtotal = product.getPrice() * quantity;
                    total += subtotal;
                    System.out.printf("✓ 购买成功: %s (ID: %s) × %d = ¥%.2f\n",
                            product.getName(), productId, quantity, subtotal);
                }
            } else {
                System.out.printf("✗ 购买失败: 商品ID %s，原因: %s\n", productId, response);
                allSuccessful = false;
                failedItems.put(productId, quantity);
            }
        }

        if (allSuccessful) {
            System.out.printf("\n结算完成！总计: ¥%.2f\n", total);
            shoppingCart.clear();
            System.out.println("感谢您的购买！");
        } else {
            System.out.println("\n部分商品购买失败，请检查库存后重试");
            // 保留失败的商品在购物车中
            shoppingCart.keySet().removeIf(key -> !failedItems.containsKey(key));
        }
    }

    private void addProduct() {
        System.out.println("\n--- 添加新商品 ---");
        System.out.print("商品ID: ");
        String id = scanner.nextLine();
        System.out.print("商品名称: ");
        String name = scanner.nextLine();
        System.out.print("价格: ");
        double price = getDoubleInput("");
        System.out.print("库存: ");
        int stock = getIntInput("");

        System.out.print("请输入标签（用逗号分隔，直接回车跳过）: ");
        String tagsInput = scanner.nextLine();
        Set<String> tags = new HashSet<>();
        if (!tagsInput.trim().isEmpty()) {
            String[] tagArray = tagsInput.split(",");
            for (String tag : tagArray) {
                tags.add(tag.trim());
            }
        }

        Product newProduct = new Product(id, name, price, stock, tags);

        Object response = sendRequest("ADD_PRODUCT", currentUser, newProduct);
        System.out.println("服务器响应: " + response);
    }

    private void updateProductInfo() {
        while (true) {
            System.out.println("\n--- 更新商品信息 ---");
            System.out.println("1. 更新商品价格");
            System.out.println("2. 更新商品库存");
            System.out.println("3. 管理商品标签");
            System.out.println("4. 返回主菜单");
            System.out.print("请选择操作: ");

            int choice = getIntInput("");

            switch (choice) {
                case 1:
                    updateProductPrice();
                    break;
                case 2:
                    updateProductStock();
                    break;
                case 3:
                    manageProductTags();
                    break;
                case 4:
                    return;
                default:
                    System.out.println("无效的选择，请重新输入！");
            }

            System.out.print("是否继续更新其他商品信息? (y/n): ");
            String continueInput = scanner.nextLine().trim();
            if (!continueInput.equalsIgnoreCase("y")) {
                break;
            }
        }
    }

    private void updateProductPrice() {
        System.out.print("请输入要更新价格的商品ID: ");
        String productId = scanner.nextLine();

        // 先获取当前商品信息
        List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
        Product existingProduct = products.stream()
                .filter(p -> p.getId().equals(productId))
                .findFirst()
                .orElse(null);

        if (existingProduct == null) {
            System.out.println("商品不存在！");
            return;
        }

        System.out.println("当前商品价格: ¥" + existingProduct.getPrice());
        System.out.print("请输入新价格: ");
        double newPrice = getDoubleInput("");

        if (newPrice < 0) {
            System.out.println("价格不能为负数！");
            return;
        }

        existingProduct.setPrice(newPrice);
        Object response = sendRequest("UPDATE_PRODUCT", currentUser, existingProduct);
        System.out.println("服务器响应: " + response);
    }

    private void updateProductStock() {
        System.out.print("请输入要更新库存的商品ID: ");
        String productId = scanner.nextLine();

        // 先获取当前商品信息
        List<Product> products = (List<Product>) sendRequest("GET_ALL_PRODUCTS");
        Product existingProduct = products.stream()
                .filter(p -> p.getId().equals(productId))
                .findFirst()
                .orElse(null);

        if (existingProduct == null) {
            System.out.println("商品不存在！");
            return;
        }

        System.out.println("当前商品库存: " + existingProduct.getStock());
        System.out.print("请输入新库存: ");
        int newStock = getIntInput("");

        if (newStock < 0) {
            System.out.println("库存不能为负数！");
            return;
        }

        existingProduct.setStock(newStock);
        Object response = sendRequest("UPDATE_PRODUCT", currentUser, existingProduct);
        System.out.println("服务器响应: " + response);
    }

    private void manageProductTags() {
        System.out.println("\n--- 管理商品标签 ---");
        System.out.print("请输入商品ID: ");
        String productId = scanner.nextLine();

        // 先获取当前标签
        Object tagsResponse = sendRequest("GET_PRODUCT_TAGS", productId);
        if (!(tagsResponse instanceof Set)) {
            System.out.println("获取标签失败: " + tagsResponse);
            return;
        }

        @SuppressWarnings("unchecked")
        Set<String> currentTags = (Set<String>) tagsResponse;
        System.out.println("当前标签: " + currentTags);

        System.out.println("1. 添加标签");
        System.out.println("2. 移除标签");
        System.out.println("3. 清空所有标签");
        System.out.print("请选择操作: ");

        int choice = getIntInput("");

        switch (choice) {
            case 1:
                System.out.print("请输入要添加的标签: ");
                String newTag = scanner.nextLine();
                Object addResponse = sendRequest("ADD_TAG", currentUser, productId, newTag);
                System.out.println("服务器响应: " + addResponse);
                break;

            case 2:
                System.out.print("请输入要移除的标签: ");
                String removeTag = scanner.nextLine();
                Object removeResponse = sendRequest("REMOVE_TAG", currentUser, productId, removeTag);
                System.out.println("服务器响应: " + removeResponse);
                break;

            case 3:
                // 清空标签：移除所有标签
                for (String tag : currentTags) {
                    sendRequest("REMOVE_TAG", currentUser, productId, tag);
                }
                System.out.println("已清空所有标签");
                break;

            default:
                System.out.println("无效的选择！");
        }
    }

    private void deleteProduct() {
        System.out.println("\n--- 删除商品 ---");
        System.out.print("请输入要删除的商品ID: ");
        String productId = scanner.nextLine();

        Object response = sendRequest("DELETE_PRODUCT", currentUser, productId);
        System.out.println("服务器响应: " + response);
    }

    private void backupData() {
        System.out.println("\n--- 数据备份 ---");
        Object response = sendRequest("BACKUP_DATA", currentUser);
        System.out.println("服务器响应: " + response);
    }

    // 通用的请求发送方法
    private Object sendRequest(String requestType, Object... params) {
        try (Socket socket = new Socket(SERVER_HOST, SERVER_PORT);
             ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
             ObjectInputStream ois = new ObjectInputStream(socket.getInputStream())) {

            oos.writeObject(requestType);
            for (Object param : params) {
                oos.writeObject(param);
            }
            oos.flush();

            return ois.readObject();

        } catch (ConnectException e) {
            return "ERROR：无法连接到服务器，请确保服务器已启动！";
        } catch (IOException | ClassNotFoundException e) {
            return "ERROR：请求过程中发生错误: " + e.getMessage();
        }
    }

    // 工具方法：获取整数输入
    private int getIntInput(String prompt) {
        while (true) {
            if (!prompt.isEmpty()) {
                System.out.print(prompt);
            }
            if (scanner.hasNextInt()) {
                int value = scanner.nextInt();
                scanner.nextLine(); // 消费换行符
                return value;
            } else {
                System.out.println("请输入有效的数字！");
                scanner.nextLine(); // 清除无效输入
            }
        }
    }

    // 工具方法：获取浮点数输入
    private double getDoubleInput(String prompt) {
        while (true) {
            if (!prompt.isEmpty()) {
                System.out.print(prompt);
            }
            if (scanner.hasNextDouble()) {
                double value = scanner.nextDouble();
                scanner.nextLine(); // 消费换行符
                return value;
            } else {
                System.out.println("请输入有效的数字！");
                scanner.nextLine(); // 清除无效输入
            }
        }
    }

    public static void main(String[] args) {
        EStoreClient client = new EStoreClient();
        client.start();
    }
}